#include "plot.h"
#include "signaldata.h"
#include "datacurve.h"
#include "qwt_symbol.h"
#include <QApplication>
#include <qwt_scale_div.h>
#include <qwt_plot_grid.h>
#include <qwt_plot_curve.h>
#include <qwt_plot_directpainter.h>
#include <qwt_plot_zoomer.h>
#include <qwt_plot_magnifier.h>
#include <qwt_plot_panner.h>
Plot::Plot(QWidget *parent)
: QwtPlot(parent), x_interval(0.0, 10.0), y_interval(-1, 1),
data_curve(new DataCurve()), interval_point_num(1), last_t(0), last_feq(0)
{
	QFont yfont("Courier New", 10);
	setAxisFont(QwtPlot::yLeft, yfont);
	setAxisScale(QwtPlot::xBottom, x_interval.minValue(), x_interval.maxValue());
	setAxisScale(QwtPlot::yLeft, y_interval.minValue(), y_interval.maxValue());
	setAxisMaxMajor(QwtPlot::xBottom, 10);
	setAxisMaxMajor(QwtPlot::yLeft, 10);
	data_curve->setStyle(QwtPlotCurve::Lines);
	data_curve->setRenderHint(QwtPlotItem::RenderAntialiased, true);
	data_curve->setPaintAttribute(QwtPlotCurve::ClipPolygons, false);
	data_curve->setPen(Qt::blue, 1);
	data_curve->attach(this);

    setAutoReplot(true);
    canvas()->setStyleSheet(  
        "border: 2px solid DarkCyan;"
        "border-radius: 10px;"
        "background-color: qlineargradient( x1: 0, y1: 0, x2: 0, y2: 1,"
        "stop: 0 LemonChiffon, stop: 1 PaleGoldenrod );"
        );

	QwtPlotGrid *grid = new QwtPlotGrid();
	grid->setPen(Qt::gray, 0.0, Qt::DotLine);
	grid->enableX(true);
	grid->enableXMin(true);
	grid->enableY(true);
	grid->enableYMin(false);
	grid->attach(this);

	panner = new QwtPlotPanner(canvas());
	magnifier = new QwtPlotMagnifier(canvas());

	zoomer = new QwtPlotZoomer(QwtPlot::xBottom, QwtPlot::yLeft,canvas());
	zoomer->setRubberBand(QwtPicker::RectRubberBand);
	zoomer->setRubberBandPen(QColor(Qt::red));
	zoomer->setTrackerMode(QwtPicker::ActiveOnly);
	zoomer->setTrackerPen(QColor(Qt::red));
	initZoomer();

	direct_painter = new QwtPlotDirectPainter();

	data_curve->setFeq(1);
	interval_point_total = x_interval.width()*1 + 1;
}
void Plot::updateXAxis()
{
	int width = x_interval.width();
	x_interval.setMinValue(x_interval.maxValue());
	x_interval.setMaxValue(x_interval.maxValue() + width);

	QwtScaleDiv scaleDiv = axisScaleDiv(QwtPlot::xBottom);
	scaleDiv.setInterval(x_interval);

	for (int i = 0; i < QwtScaleDiv::NTickTypes; i++)
	{
		QList<double> ticks = scaleDiv.ticks(i);
		for (int j = 0; j < ticks.size(); j++)
			ticks[j] += width;
		scaleDiv.setTicks(i, ticks);
	}
	setAxisScaleDiv(QwtPlot::xBottom, scaleDiv);
	replot();
}
void Plot::resetXAxis()
{
	int width = x_interval.width();
	x_interval.setMinValue(0);
	x_interval.setMaxValue(width);

	QwtScaleDiv scaleDiv = axisScaleDiv(QwtPlot::xBottom);
	scaleDiv.setInterval(x_interval);
	QList<double> minorticks = scaleDiv.ticks(QwtScaleDiv::MinorTick);
	QList<double> majorticks = scaleDiv.ticks(QwtScaleDiv::MajorTick);
	int minor_num = minorticks.size();
	int major_num = majorticks.size();
	int minortick_num_between_majortick = minor_num / (major_num - 1);
	float major_in = (float)width / (major_num - 1);
	float minor_in = major_in / (minortick_num_between_majortick+1);
	int idx = 0;
	for (int i = 0; i < major_num - 1; i++)
		for (int j = 1; j < minortick_num_between_majortick;j++,idx++)
			minorticks[idx] = j*minor_in + i;
	for (int i = 0; i < major_num; i++)
		majorticks[i] = i*major_in;
	scaleDiv.setTicks(QwtScaleDiv::MinorTick, minorticks);
	scaleDiv.setTicks(QwtScaleDiv::MajorTick, majorticks);
	setAxisScaleDiv(QwtPlot::xBottom, scaleDiv);
	replot();
}


void Plot::updateXAxisWidth(double width)
{
	x_interval.setMaxValue(x_interval.minValue() + width);
	setAxisScale(QwtPlot::xBottom,
		x_interval.minValue(), x_interval.maxValue());
	interval_point_total = x_interval.width()*data_curve->feq + 1;
	replot();
}

void Plot::plot(int t, double y,int feq)
{
	if (t < last_t)
	{ 
		last_t = 0;
		interval_point_num = 0;
		data_curve->clear();
		resetXAxis();
	}
	if (feq == 0) feq = 50;
	data_curve->addPoint((double)t / 1000, y);
	interval_point_num += (t - last_t) / data_curve->ts;
	last_t = t;
	if (last_feq != feq)
	{
		last_feq = feq;
		data_curve->setFeq(feq);
		interval_point_total = x_interval.width()*feq + 1;
		interval_point_num = (t - x_interval.minValue() * 1000) / data_curve->ts + 1;
	}
	int d_size = data_curve->dataSize();
	direct_painter->drawSeries(static_cast<QwtPlotSeriesItem*>(data_curve),
		d_size - 2, d_size - 1);
	if (interval_point_num >= interval_point_total)
	{
		updateXAxis();
		data_curve->updateRect();
		interval_point_num = interval_point_num - interval_point_total + 1;
	}

}
void Plot::setKeyZoomer()
{
	panner->setEnabled(false);
	magnifier->setEnabled(false);
	zoomer->setEnabled(true);
}
void Plot::setWheelZoomer()
{
	zoomer->setEnabled(false);
	panner->setEnabled(true);
	magnifier->setEnabled(true);
	panner->setAxisEnabled(QwtPlot::xBottom, true);
	magnifier->setAxisEnabled(QwtPlot::xBottom, true);
}
void Plot::initZoomer()
{
	zoomer->setEnabled(false);
	panner->setEnabled(true);
	magnifier->setEnabled(true);
	panner->setAxisEnabled(QwtPlot::xBottom, false);
	magnifier->setAxisEnabled(QwtPlot::xBottom, false);
}
void Plot::autoScale()
{
	setAxisScale(QwtPlot::xBottom,
		x_interval.minValue(), x_interval.maxValue());
	setAxisAutoScale(QwtPlot::yLeft, true);
	replot();
	setAxisAutoScale(QwtPlot::yLeft, false);
}
void Plot::mouseDoubleClickEvent(QMouseEvent *e)
{
	if (e->buttons() == Qt::LeftButton)
		emit maximize(this);
}
Plot::~Plot()
{

}
